package cn.signalpha.modules.com.controller.admin;

import cn.signalpha.common.constant.AppConstant;
import cn.signalpha.common.utils.Assert;
import cn.signalpha.core.boot.ctrl.BaseController;
import cn.signalpha.core.excel.util.ExcelUtil;
import cn.signalpha.core.jwt.JwtUtil;
import cn.signalpha.core.mp.support.Condition;
import cn.signalpha.core.mp.support.Query;
import cn.signalpha.core.tool.api.R;
import cn.signalpha.core.tool.utils.*;
import cn.signalpha.modules.auth.utils.TokenUtil;
import cn.signalpha.modules.com.dto.UserDTO;
import cn.signalpha.modules.com.entity.User;
import cn.signalpha.modules.com.excel.UserExcel;
import cn.signalpha.modules.com.service.UserService;
import cn.signalpha.modules.com.vo.UserTreeVO;
import cn.signalpha.modules.com.vo.UserVO;
import cn.signalpha.modules.com.wrapper.UserWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import io.swagger.annotations.*;
import lombok.AllArgsConstructor;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import static cn.signalpha.common.constant.MsgConstant.OBJECT_NULL;

/**
 * 控制器
 *
 * @author signalpha
 */
@RestController
@AllArgsConstructor
@RequestMapping(AppConstant.APPLICATION_USER_NAME + "/admin/user")
@Api(value = "用户", tags = "用户")
public class UserController extends BaseController {

	private final UserService userService;

	@GetMapping("/page")
	@ApiImplicitParams({
		@ApiImplicitParam(name="mobile", dataType = "string", value = "电话"),
		@ApiImplicitParam(name="nickName", dataType = "string", value = "昵称"),
		@ApiImplicitParam(name="status", dataType = "string", value = "状态"),
		@ApiImplicitParam(name="level", dataType = "string", value = "等级"),
	})
	@ApiOperation(value = "分页", notes = "")
	public R<IPage<UserVO>> page(@ApiIgnore @RequestParam Map<String, Object> params, Query query) {
		return R.data(userService.selectUserPage(Condition.getPage(query), params));
	}

	@GetMapping("/export")
	@ApiOperation(value = "导出excel", notes = "")
	public void export(@ApiIgnore @RequestParam Map<String, Object> params, HttpServletResponse response) {
		List<UserExcel> list = userService.selectUserExcel(params);
		ExcelUtil.export(response, DateUtil.time(), StringPool.EMPTY, list, UserExcel.class);
	}

	@GetMapping("/chain")
	@ApiOperation(value = "用户推荐连")
	public R<List<UserTreeVO>> chain(@RequestParam Long parentId) {
		return R.data(userService.lazyTree(parentId));
	}

	@GetMapping("/lazy-tree")
	@ApiOperation(value = "懒加载用户树")
	public R<List<UserTreeVO>> tree(@RequestParam Long parentId) {
		return R.data(userService.lazyTree(parentId));
	}

	@GetMapping("/info")
	@ApiOperation(value = "详情", notes = "传入id")
	public R<User> info(@ApiParam(value = "主键", required = true) @RequestParam Long id) {
		return R.data(UserWrapper.build().entityVO(userService.getById(id)));
	}

	@PostMapping("/update")
	@ApiOperation(value = "修改", notes = "传入user")
	public R update(@Valid @RequestBody UserDTO userDTO) {
		User user = Objects.requireNonNull(userService.getById(userDTO.getId()), OBJECT_NULL);
		if(StringUtil.isNotBlank(userDTO.getMobile()) && !Objects.equals(user.getMobile(), userDTO.getMobile())){
			if(userService.countByMobile(userDTO.getMobile())){
				return R.fail(StringUtil.format("当前手机号 [{}] 已注册", userDTO.getMobile()));
			}
		}
		if(StringUtil.isNotBlank(userDTO.getAccount()) &&  !Objects.equals(user.getAccount(), userDTO.getAccount())){
			if(userService.countByAccount(userDTO.getAccount())){
				return R.fail(StringUtil.format("当前邀请码 [{}] 已存在", userDTO.getAccount()));
			}
		}
		userDTO.setUpdateTime(DateUtil.now());
		userService.removeBaseById(user.getId());
		return R.status(userService.updateById(BeanUtil.copy(userDTO, User.class)));
	}

	@PostMapping("/update/status")
	@ApiOperation(value = "修改状态", notes = "")
	public R updateStatus(@Valid @RequestBody UserDTO.UpdateStatusDTO statusDTO) {
		JwtUtil.removeAccessToken(TokenUtil.DEFAULT_TENANT_ID, statusDTO.getId().toString());
		return R.status(userService.updateById(BeanUtil.copy(statusDTO, User.class)));
	}

	@PostMapping("/update/parentId")
	@ApiOperation(value = "修改推荐人", notes = "")
	public R updatePid(@Valid @RequestBody UserDTO.UpdatePidDTO pidDTO) {
		User user = userService.getById(pidDTO.getParentId());
		Assert.isNull(user, "目标id不存在");
		Assert.isFalse(Objects.equals(pidDTO.getId(), pidDTO.getParentId()), "用户id与目标id一致");
		Assert.isFalse(Func.toLongList(user.getChain()).contains(pidDTO.getId()), "禁止将上级转移到下级");
		return R.status(userService.updateParentId(Collections.singletonList(pidDTO.getId()), pidDTO.getParentId()));
	}

	@PostMapping("/update/tag")
	@ApiOperation(value = "批量设置标签", notes = "")
	public R transfer(@Valid @RequestBody UserDTO.UpdateTagDTO updateTagDTO) {
		return R.status(userService.update(Wrappers.<User>lambdaUpdate().set(User::getTagId, updateTagDTO.getTagId()).in(User::getId, Func.toLongList(updateTagDTO.getId()))));
	}

	@PostMapping("/reset/password")
	@ApiOperation(value = "初始化密码")
	public R updateResetPassword(@ApiParam(value = "主键集合", required = true) @RequestParam String ids) {
		return R.status(userService.resetPassword(ids));
	}

	@PostMapping("/remove")
	@ApiOperation(value = "删除", notes = "传入ids")
	public R remove(@ApiParam(value = "主键集合", required = true) @RequestParam String ids) {
		return R.status(userService.removeByIds(Func.toLongList(ids)));
	}

}
